`ifndef MY_DRIVER__SV
`define MY_DRIVER__SV

import uvm_pkg::*;
  `include "uvm_macros.svh"
  `include "fifo_transcation.sv"
  
class fifo_driver extends uvm_driver#(fifo_transcation);
  virtual fifo_if vif;
  
  `uvm_component_utils(fifo_driver)
  function new(string name = "fifo_driver",uvm_component parent = null);
    super.new(name,parent);
  endfunction
  
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
	`uvm_info("fifo_driver","build_phase is called",UVM_LOW)
	if(!uvm_config_db#(virtual fifo_if)::get(this,"","vif",vif))
	  `uvm_fatal("fifo_driver","vif must be set")
  endfunction
  
  extern task main_phase(uvm_phase phase);
  extern task drive_one_data(fifo_transcation tr);
endclass

task fifo_driver::main_phase(uvm_phase phase);
////这里注释掉raise drop 是为了让仿真自动结束，不然一直会卡在while(1)无法自动跳出////
  //phase.raise_objection(this);
  `uvm_info("fifo_driver","main_phase is called",UVM_LOW)
  fork
    //wait 等待一次    @一直等待
    @(vif.init_done == 0)begin
	  vif.wr_data <= 'b0;
	end
	
	 
	@(vif.init_done == 1) begin
      //for(int i = 0;i < 30;i++) begin
	  while(1)begin
	    @(posedge vif.wrclk);
	    if(vif.wr_full == 0)begin
		  //while(1)begin
		    seq_item_port.get_next_item(req);
		    //vif.wr_data = req.dmac;
			drive_one_data(req);
		    `uvm_info("fifo_driver",$sformatf("drive one data:%d at %0t",vif.wr_data,$time),UVM_LOW)
		    seq_item_port.item_done();
			`uvm_info("fifo_driver",$sformatf("time is %0t",$time),UVM_LOW)
		  //end
		end
	    else begin
	      vif.wr_data <= vif.wr_data;
	      `uvm_info("fifo_driver","fifo is full",UVM_LOW)
	    end
      end
	  //end
    end
	
  join
  //phase.drop_objection(this);
  `uvm_info("fifo_driver","drive is finished",UVM_LOW)
endtask

task fifo_driver::drive_one_data(fifo_transcation tr);
  bit[15:0] data_q;
  
  data_q = tr.dmac;
  vif.wr_data = data_q;
endtask
`endif
